# -*- coding:utf-8 -*-  

# Contact with the author by :
# itech001@126.com
# www.cnblogs.com/itech

import os
import sys
import socketserver
import logging
import re

import PyRRCommon

logger = PyRRCommon.PyRRLogger()
# why output twice when using the below code 
#logger = PyRRCommon.PyRRLogger().instance()

class RemoteRunningTCPHandler(socketserver.StreamRequestHandler):
  def handle(self):

    logger.debug("Recived from: %s \n:" % self.client_address[0])

    # self.rfile is a file-like object created by the handler;
    # we can now use readline() instead of raw recv() calls
    firstline = self.rfile.readline().strip()
    logger.debug(firstline)
    
    # decide the coming stream is command or script file by the first line.
    # if the first line is farmated as "<ext|linenum>", the coming stream is script file,
    # otherwise the coming stream is command.
    mobj = re.match('^\<(.*?)\|(\d+)\>$',str(firstline,'utf-8'))
    if not mobj:
        cmd = str(firstline,'utf-8')
        rc, stdo, stde = PyRRCommon.run_command_with_output(cmd)
        logger.debug("OutPut is: %s" % stdo)
        self.wfile.write(bytes(stdo,'utf-8'))
    else:
        # get the extension and line number for the script file.
        ext = mobj.group(1)
        linenum = int(mobj.group(2))
        logger.debug("ext is: %s" % ext)
        logger.debug("line num is : %s" % str(linenum))
    
        data = bytes('','utf-8')
        for i in range(linenum) :
          line = self.rfile.readline()
          line += bytes(os.linesep,'utf-8')
          data += line
        logger.debug("Data is: %s" % str(data,'utf-8'))
        
        # Save to temp file and then execute it.
        tempdir = PyRRCommon.temp_dir()
        md5hex = PyRRCommon.cal_MD5(data)
        tempfile = os.path.join(tempdir,md5hex + ext)
        logger.debug("Temp file : %s" % tempfile)
        PyRRCommon.write_file(tempfile,data)
        
        # for script file, to add excutable file.
        cmd = tempfile
        excutable = PyRRCommon.get_excutable_by_ext(ext)
        if excutable:
            cmd= excutable + ' ' + cmd
        # if in the *unix os, also need assign excutable permission
        # Todo:
        rc, stdo, stde = PyRRCommon.run_command_with_output(cmd)
        
        # Likewise, self.wfile is a file-like object used to write back
        # to the client
        logger.debug("OutPut is: %s" % stdo)
        self.wfile.write(bytes(stdo,'utf-8'))

if __name__ == "__main__":
    usage = """
    Usage:
    sys.argv[0] HOST PORT.
    Defaultly HOST will be the machine name and PORT will be 9999.
    """

    HOST, PORT = PyRRCommon.hostname(), 9999

    if len(sys.argv) >= 2 : HOST = sys.argv[1]
    if len(sys.argv) >= 3 : PORT = int(sys.argv[2])
      
    # Create the server, binding to localhost and port
    server = socketserver.TCPServer((HOST, PORT), RemoteRunningTCPHandler)

    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    print("  The Server will keep running until you interrupt the program with Ctril-C.")
    server.serve_forever()
